package com.search;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Stemmer {

	// stemming result
	private Map<String, Integer> termFreq;
	private Integer maxTf;
	private ArrayList<String> stemmedQuery = new ArrayList<String>();
	private ArrayList<ArrayList<String>> stemmedPhrase;

	// constants
	private ArrayList<String> stopWords;

	// constructor, initialize the stemmer and read a list of stop words
	public Stemmer(String path) throws FileNotFoundException {
		stopWords = new ArrayList<String>();
		Scanner input = new Scanner(new File(path));

		while (input.hasNext()) {
			stopWords.add(input.next());
		}
		input.close();
	}

	public void stem(ArrayList<String> content) {
		// result
		termFreq = new HashMap<String, Integer>();
		maxTf = 0;

		if (content != null && content.size() > 0) {

			// temporary data
			Porter porter = new Porter();
			Integer tf = 0;

			for (String term : content) {

				String stemmedTerm = porter.stripAffixes(term); // stem words
				if (!stopWords.contains(stemmedTerm)) { // remove stop words

					// add to resultant list
					if (termFreq.containsKey(stemmedTerm)) {
						tf = termFreq.get(stemmedTerm) + 1;
					} else {
						tf = 1;
					}
					if (tf > maxTf) {
						maxTf = tf;
					}
					termFreq.put(stemmedTerm, tf);
				}
			}
		}
	}
	
	public void stemQuery(String query) {
		Porter porter = new Porter();
		
		List<String> list = new ArrayList<String>();
		Matcher m = Pattern.compile("([^\"]\\S*|\".+?\")\\s*").matcher(query);
		while (m.find())
			list.add(m.group(1));

		ArrayList<String> queryNoPhrase = new ArrayList<String>(list);
		stemmedPhrase = new ArrayList<ArrayList<String>>();
		for (int i = 0; i < queryNoPhrase.size(); i++) {
			//System.out.println(stemmedQuery.get(i));
			if(queryNoPhrase.get(i).contains("\"")){
				String phrase = queryNoPhrase.get(i).substring(1, queryNoPhrase.get(i).length()-1);
				List<String> phraseList = Arrays.asList(phrase.split("[^a-zA-Z0-9]"));
				
				ArrayList<String> phraseArrayList = new ArrayList<String>(phraseList);
				phraseArrayList.removeAll(Arrays.asList("", null));
				ArrayList<String> stemmedphraseList = new ArrayList<String>();
				for (String term : phraseArrayList) {
					String stemmedTerm = porter.stripAffixes(term); // stem words		
					if (!stopWords.contains(stemmedTerm) && !stemmedphraseList.contains(stemmedTerm)) { // remove stop words
						stemmedphraseList.add(stemmedTerm);
					}
				}
				
				stemmedPhrase.add(stemmedphraseList);
				queryNoPhrase.remove(queryNoPhrase.get(i));
				i--;
			}							
		}
		
		queryNoPhrase.removeAll(Arrays.asList("", null));

		for (String term : queryNoPhrase) {
			String stemmedTerm = porter.stripAffixes(term); // stem words		
			if (!stopWords.contains(stemmedTerm) && !stemmedQuery.contains(stemmedTerm)) { // remove stop words
				stemmedQuery.add(stemmedTerm);
			}
		}
	}
	
	public void cleanStemmer(){
		stemmedQuery = new ArrayList<String>();
		stemmedPhrase = new ArrayList<ArrayList<String>>();
	}
	

	public Map<String, Integer> getTermFreq() {
		return termFreq;
	}

	public Integer getMaxTf() {
		return maxTf;
	}
	
	public ArrayList<String> getStemmedQuery() {
		return stemmedQuery;
	}
	
	public ArrayList<ArrayList<String>> getStemmedPhrase() {
		return stemmedPhrase;
	}

}
